package com.lcp.dingqibao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.lcp.abstraction.*;
import com.lcp.abstraction.authentication.LoginUser;
import com.lcp.abstraction.exception.WarnCommonException;
import com.lcp.coremodel.DbEntity;
import com.lcp.dingqibao.model.OAUserModel;
import com.lcp.dingqibao.model.OAUserVo;
import com.lcp.dingqibao.model.RemoteCallbackModel;
import com.lcp.dingqibao.service.DingProcessService;
import com.lcp.qibao.service.UserInfoService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;

@Slf4j
@Service
public class DingProcessServiceImpl implements DingProcessService {
    @Autowired
    RestTemplate restTemplate;

    @Autowired
    AppHolderService appHolderService;
    @Autowired
    DataAccess dataAccess;
    @Value("${custom.wf-api-server:}")
    private String urlTemplate;

    @Autowired
    UserInfoService userService;

    @Override
    public List<DbEntity> getAllProcessListByUserId(String userId) {
        if (StringUtils.isEmpty(userId)) {
            return List.of();
        }
        QueryOption queryOption = new QueryOption("wf_oins");
        queryOption.setFixField("fins_id.apply_user,fins_id.name,fins_id.service_name,task_name,start_time");
        TableFilterWrapper filterWrapper = TableFilterWrapper.and();
        filterWrapper.eq("process_status", "0");
        filterWrapper.eq("user_id", userId).eq("process_status", "0");
        filterWrapper.in("service_id", String.join(",", getEnableAppList()));

        queryOption.setTableFilter(filterWrapper.build());
        List<DbEntity> list = dataAccess.queryAllData(queryOption).getData();
        list.parallelStream().forEach(item -> {
            item.put("_from", "qibao");
        });
        return list;
    }

    private List<String> getEnableAppList() {
        QueryOption queryOption = new QueryOption("wf_service");
        queryOption.setFixField("id,enable_app");
        TableFilterWrapper filterWrapper = TableFilterWrapper.and();
        filterWrapper.eq("enable_app", "1");
        queryOption.setTableFilter(filterWrapper.build());
        List<DbEntity> list = dataAccess.queryAllData(queryOption).getData();
        if (list.isEmpty()) {
            return List.of();
        }
        List<String> listId = new ArrayList<>();
        list.forEach(item -> {
            listId.add(item.get("id").toString());
        });
        return listId;
    }

    @Override
    public List<DbEntity> getAllProcessListByUserCode(String userCode) {
        return List.of();
    }


    @Override
    @SneakyThrows
    public Object getApprovalForm(String oInsId) {
        if (StringUtils.isEmpty(oInsId)) {
            throw new ParameterNotFoundException("oInsId");
        }
        String url = String.format("%s/wft/getApprovalForm", urlTemplate);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("oInsId", oInsId);
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", appHolderService.getUser().getToken());
        //app标识放入header
        headers.add("isApp", "1");
        HttpEntity<MultiValueMap<String, String>> formEntity = new HttpEntity<>(map, headers);
        try {
            log.debug(formEntity.toString());
            RemoteCallbackModel result = restTemplate.postForObject(url, formEntity, RemoteCallbackModel.class);
            if (result == null || result.getSuccess() == null) {
                throw new WarnCommonException("流程getApprovalForm报错，通过接口流转流程返回值不应该为空");
            }
            if (result.getSuccess().equals(1)) {
                return result.getData();
            } else {
                throw new WarnCommonException(result.getMessage());
            }
        } catch (Exception exception) {
            log.error("流程getApprovalForm报错" + url, exception);
            throw new WarnCommonException("流程getApprovalForm报错" + exception.getMessage());
        }
    }

    @Override
    @SneakyThrows
    public String getLoginUser(OAUserModel userBo) {

        String URL = String.format("%s%s", urlTemplate, "/invoke/method");
        // 接入开发平台的header
        HttpHeaders headers = new HttpHeaders();
        headers.add("token", appHolderService.getUser().getToken());
        //headers.add("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1Y28iOiJhZG1pbjEiLCJhdWQiOiI2ODgxNjQwNzA2ODcyNDgzODQiLCJ1bmEiOiJhZG1pbjEiLCJ1b3IiOiI2ODgxNTc0ODY2MDMwNDY5MTIiLCJleHAiOjE3MzYzNjg2MzZ9.ClXprkGtW7gLAbM8FmkWB3ST4VVV3cxICt3Eg7ytzT4");
        headers.setContentType(MediaType.APPLICATION_JSON);
        HashMap<String, Object> newEntity = new HashMap<>();
        newEntity.put("pageId", "773227438074236928");
        newEntity.put("appId", "769255580404551680");
        newEntity.put("methodId", "698533841412820992");
        List<OAUserModel> liUser = new ArrayList<>();
        liUser.add(userBo);
        var strUser = JSON.toJSONString(liUser);
        HashMap<String, Object> userEntity = new HashMap<>();
        userEntity.put("user", strUser);
        newEntity.put("data", userEntity);
        HttpEntity<String> httpEntity = new HttpEntity<String>(JSON.toJSONString(newEntity), headers);
        try {
            log.info("新增用户url:{},入参{}", URL, httpEntity);
            ResponseEntity<JSONObject> exchange = restTemplate.exchange(URL, HttpMethod.POST, httpEntity, JSONObject.class);
            log.info("新增用户返回：" + exchange);
            JSONObject body = exchange.getBody();
            if (body != null && body.get("data") != null) {
                var array = body.get("data");
                var oaUsers = JSON.parseArray(JSON.toJSONString(array), OAUserVo.class);
                //根据新用户生成token
                if (!CollectionUtils.isEmpty(oaUsers)) {
                    LoginUser tokenUser = new LoginUser();
                    tokenUser.setId(TypeConverterUtils.object2Long(oaUsers.get(0).getFieldValue()));
                    tokenUser.setCode(userBo.getPersonnel_no());
                    tokenUser.setCode(userBo.getChinese_name());
                    var orgId = "";
                    if (oaUsers.get(0).getOtherField() != null) {
                        orgId = TypeConverterUtils.object2String(oaUsers.get(0).getOtherField().getOrgId(), "");
                    }
                    tokenUser.setOrgId(orgId);
                    return userService.createUserToken(tokenUser);
                }
            } else {
                throw new WarnCommonException("获取用户信息异常，请重试");
            }
        } catch (Exception ex) {
            log.error("创建用户信息异常", ex);
        }
        throw new WarnCommonException("获取用户信息异常，请重试");
    }
}
